﻿#include "GUIGeometryLineDialog.h"
#include "ui_GUIGeometryLineDialog.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "FITK_Kernel/FITKCore/FITKOperatorRepo.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsGeometryData.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKGeoInterfaceFactory.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoModelOperLine.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeomTools.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoModelPoint.h"
#include "PickDataProvider/GUIPickInfo.h"
#include "FITK_Kernel/FITKCore/FITKActionOperator.h"
#include "OperatorsInterface/GraphEventOperator.h"

#include "PickDataProvider/PickedData.h"
#include "PickDataProvider/PickedDataProvider.h"

#include <QMessageBox>

namespace GUI {

    GUIGeometryLineDialog::GUIGeometryLineDialog(Core::FITKActionOperator* oper, QWidget* parent)
        : GUIGeometryBaseDialog(nullptr, oper, parent), _ui(new Ui::GUIGeometryLineDialog)
    {
        _ui->setupUi(this);
        this->createGeometryObj(Interface::FITKGeoEnum::FITKGeometryComType::FGTSegment);//有限线段
        this->init();
    }

    GUIGeometryLineDialog::GUIGeometryLineDialog(Interface::FITKAbsGeoModelSegment* obj, Core::FITKActionOperator* oper, QWidget* parent)
        : GUIGeometryBaseDialog(obj, oper, parent), _ui(new Ui::GUIGeometryLineDialog)
    {
        _ui->setupUi(this);

        this->init();
    }

    GUIGeometryLineDialog::~GUIGeometryLineDialog()
    {
        if (_ui) {
            delete _ui;
            _ui = nullptr;
        }
    }

    void GUIGeometryLineDialog::init()
    {
        setWindowTitle(tr("Curve"));//线

        Interface::FITKAbsGeoModelSegment* geoData = dynamic_cast<Interface::FITKAbsGeoModelSegment*>(_obj);
        Acoustics::FITKAcousticsGeometryData* geometryData = FITKAPP->getGlobalData()->getGeometryData<Acoustics::FITKAcousticsGeometryData>();

        if (!geometryData || !geoData) return;
        //获取数据
        QString name = geometryData->checkName(tr("Curve-1"));
        if (!_isCreate) name = _obj->getDataObjectName();

        std::array<double, 3> startPointD = geoData->startPoint();//起点
        std::array<double, 3> endPointD = geoData->endPoint();//终点
        //设置界面
        _ui->lineEdit_Name->setText(name);

        //设置起点
        _ui->Point_lineEditX->setText(QString::number(startPointD.at(0)));
        _ui->Point_lineEditY->setText(QString::number(startPointD.at(1)));
        _ui->Point_lineEditZ->setText(QString::number(startPointD.at(2)));

        //设置终点
        _ui->Point_lineEditX_2->setText(QString::number(endPointD.at(0)));
        _ui->Point_lineEditY_2->setText(QString::number(endPointD.at(1)));
        _ui->Point_lineEditZ_2->setText(QString::number(endPointD.at(2)));
    }

    QString GUIGeometryLineDialog::getNameText()
    {
        return _ui->lineEdit_Name->text();
    }

    void GUIGeometryLineDialog::pickFinishedOper()
    {
        //获取拾取数据
        GraphData::PickedDataProvider* provider = GraphData::PickedDataProvider::getInstance();
        if (provider == nullptr)return;
        disconnect(provider, SIGNAL(sig_pickedOver()), this, SLOT(slotPickOverEvent()));
        QList<GraphData::PickedData*> pickList = provider->getPickedList();
        QList<int> idList = {};
        QList<int> PickedIds;
        for (GraphData::PickedData* pickData : pickList) {
            if (pickData == nullptr)continue;
            idList.append(pickData->getPickedDataObjId());
            PickedIds = pickData->getPickedIds();
        }
        //获取拾取的数据
        if (idList.isEmpty()) return;

        //根据id获取点的xyz
        std::array<double, 3> xyz = this->getPointXYZ(PickedIds.at(0));

        //精度要求7位
        if (m_Pick == 1)
        {
            _ui->Point_lineEditX->setText(QString::number(xyz.at(0), 'f', 7));
            _ui->Point_lineEditY->setText(QString::number(xyz.at(1), 'f', 7));
            _ui->Point_lineEditZ->setText(QString::number(xyz.at(2), 'f', 7));
        }
        if (m_Pick == 2)
        {
            _ui->Point_lineEditX_2->setText(QString::number(xyz.at(0), 'f', 7));
            _ui->Point_lineEditY_2->setText(QString::number(xyz.at(1), 'f', 7));
            _ui->Point_lineEditZ_2->setText(QString::number(xyz.at(2), 'f', 7));
        }
        m_Pick = -1;
    }

    void GUIGeometryLineDialog::getDataFormWidget()
    {
        Interface::FITKAbsGeoModelSegment*lineP = dynamic_cast<Interface::FITKAbsGeoModelSegment*>(_obj);

        lineP->setDataObjectName(_ui->lineEdit_Name->text());//更新线名称

        //起点
        lineP->setStartPoint(
            _ui->Point_lineEditX->text().toDouble(),
            _ui->Point_lineEditY->text().toDouble(),
            _ui->Point_lineEditZ->text().toDouble()
        );

        lineP->setEndPoint(
            _ui->Point_lineEditX_2->text().toDouble(),
            _ui->Point_lineEditY_2->text().toDouble(),
            _ui->Point_lineEditZ_2->text().toDouble()
        );
        lineP->update();
    }

    void GUIGeometryLineDialog::on_pushButtonPoint1_Pick_clicked()
    {
        //拾取对象 几何点
        //拾取方式 单独数据拾取方式。（点选+追加拾取）    
        m_Pick = 1;
        enablePickSig(GUI::GUIPickInfo::POBJGeometryVert, GUI::GUIPickInfo::PickMethod::PMSingle);
    }

    void GUIGeometryLineDialog::on_pushButtonPoint1_Pick_2_clicked()
    {
        //拾取对象 几何点
        //拾取方式 单独数据拾取方式。（点选+追加拾取）  
        m_Pick = 2;
        enablePickSig(GUI::GUIPickInfo::POBJGeometryVert, GUI::GUIPickInfo::PickMethod::PMSingle);
    }


    void GUIGeometryLineDialog::on_pushButton_OK_clicked()
    {
        if (this->checkArgc() == false)//检查数据
        {
            return;
        }
        if (_isCreate)
        {
            if (!this->createObjData())
            {
                return;
            }
        }
        else
        {
            if (!this->editObjData())
                return;
        }
        if (_oper && _obj) {
            _oper->setArgs("objID", _obj->getDataObjectID());
        }
        this->accept();
    }


    void GUIGeometryLineDialog::on_pushButton_Cancel_clicked()
    {
        _oper->setArgs("objID", -1);
        this->reject();
    }
    std::array<double, 3> GUIGeometryLineDialog::getPointXYZ(int id)
    {
        std::array<double, 3> xyz = { -1,-1,-1 };

        Interface::FITKInterfaceGeometryFactory*factory = Interface::FITKInterfaceGeometryFactory::getInstance();
        if (factory == nullptr)
        {
            return xyz;
        }
        Interface::FITKAbstractGeomToolsCreator*createor = factory->getGeomToolsCreator();
        Interface::FITKAbstractGeomPointTool *pointTool = createor->createPointTool();
        double PointArray[3];
        pointTool->getXYZ(id, PointArray);

        xyz.at(0) = PointArray[0];
        xyz.at(1) = PointArray[1];
        xyz.at(2) = PointArray[2];
        return xyz;
    }
    bool GUIGeometryLineDialog::checkArgc()
    {
        if (_ui->Point_lineEditX->text() == _ui->Point_lineEditX_2->text() &&
            _ui->Point_lineEditY->text() == _ui->Point_lineEditY_2->text() &&
            _ui->Point_lineEditZ->text() == _ui->Point_lineEditZ_2->text()
            )
        {
            //如果一致，说明选择的2个点是同一个点，不允许这样创建
            QMessageBox msgBox;
            msgBox.setIcon(QMessageBox::Warning);  // 设置消息框图标为警告图标
            msgBox.setWindowTitle(tr("warning"));
            msgBox.setText(tr("Same starting and ending point"));
            msgBox.setStandardButtons(QMessageBox::Ok);  // 设置标准按钮
            msgBox.setDefaultButton(QMessageBox::Ok);  // 设置默认按钮
            int ret = msgBox.exec();//事件循环
            return false;
        }

        //判断是否全部能转换为正确的数据
        bool ok = false;
        _ui->Point_lineEditX->text().toDouble(&ok);
        if (ok == false) { return false; }

        _ui->Point_lineEditY->text().toDouble(&ok);
        if (ok == false) { return false; }

        _ui->Point_lineEditZ->text().toDouble(&ok);
        if (ok == false) { return false; }

        _ui->Point_lineEditX_2->text().toDouble(&ok);
        if (ok == false) { return false; }

        _ui->Point_lineEditY_2->text().toDouble(&ok);
        if (ok == false) { return false; }

        _ui->Point_lineEditZ_2->text().toDouble(&ok);
        if (ok == false) { return false; }

        return true;
    }
}